﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BasePlatformNet;
using System.Threading;
using BasePlatformCommon;

namespace L9SubSet
{
	public partial class Form_CheckSubData : Form
	{
		private BaseCoreNet baseCoreNet = null;

		private int startSubIndex = -1;
		private int endSubIndex = -1;

		private byte[] refSubData = null;

		private List<byte[]> targetSubDataList = null;

		private string checkMode = "spec";

		public delegate void InitInfoDataGridDelegate(int start, int end);
		public InitInfoDataGridDelegate initInfoDataGridDelegate;
		public delegate void ShowMessageDelegate(string msg);
		public ShowMessageDelegate showMessageDelegate;
		public delegate void UpdateInfoDataGridDelegate(int rowIndex, string checkResult);
		public UpdateInfoDataGridDelegate updateInfoDataGridDelegate;
		public delegate void UpdateCheckProgressDelegate();
		public UpdateCheckProgressDelegate updateCheckProgressDelegate;

		private int needReadDataTotalLength = 0;
		private int currentReadedDataLength = 0;

		private bool isCheckingData = false;

		private string section = "CheckSubData";							// 多语言文件配置节名称

		private string tip = "提示";											// MessageBox 题头

		/*****************************************************************************************/

		// 构造函数
		public Form_CheckSubData(BaseCoreNet baseCoreNet, byte[] refSubDataPara)
		{
			InitializeComponent();

			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
			this.Font = new System.Drawing.Font(this.Font.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));

			this.baseCoreNet = baseCoreNet;

			if(refSubDataPara == null && refSubDataPara.Length != 128 * 1024)
			{
				refSubData = null;
			}
			else
			{
				refSubData = new byte[128 * 1024];
				Array.Copy(refSubDataPara, refSubData, refSubData.Length);
			}

			initEnvironment();
		}

		// 初始化运行环境
		private void initEnvironment()
		{
			initInfoDataGridDelegate = new InitInfoDataGridDelegate(initInfoDataGrid);
			showMessageDelegate = new ShowMessageDelegate(showMessage);
			updateInfoDataGridDelegate = new UpdateInfoDataGridDelegate(updateInfoDataGrid);
			updateCheckProgressDelegate = new UpdateCheckProgressDelegate(updateCheckProgress);

			startSubIndexTextBox.Text = "1";
			endSubIndexTextBox.Text = "1";

			specRadioButton.Checked = true;

			if (refSubData != null)
			{
				refSubDataRichTextBox.Text = Tools.Byte2HexString4Sub(refSubData);
			}

			targetSubDataList = new List<byte[]>();

			// 设置本地化语言
			if (LanguageOper.available == true)
			{
				setLanguageText();
			}
		}

		// 设置本地化语言
		public void setLanguageText()
		{
			if (LanguageOper.available == false)
			{
				return;
			}

			LanguageOper.SetCurrentCulture();

			tip = LanguageOper.ReadValue("Common", "tipStr");

			// 界面控件文字
			this.Text = LanguageOper.ReadValue(section, "checkSubData.Text");
			paraGroupBox.Text = LanguageOper.ReadValue(section, "paraGroupBox.Text");
			allRadioButton.Text = LanguageOper.ReadValue(section, "allRadioButton.Text");
			specRadioButton.Text = LanguageOper.ReadValue(section, "specRadioButton.Text");
			toLabel.Text = LanguageOper.ReadValue(section, "toLabel.Text");
			processTipLabel.Text = LanguageOper.ReadValue(section, "processTipLabel.Text");
			tabControl1.TabPages[0].Text = LanguageOper.ReadValue(section, "tabPages.0.Text");
			tabControl1.TabPages[1].Text = LanguageOper.ReadValue(section, "tabPages.1.Text");
			infoDataGridView.Columns[0].HeaderText = LanguageOper.ReadValue(section, "infoDataGridView.HeaderText.0");
			infoDataGridView.Columns[1].HeaderText = LanguageOper.ReadValue(section, "infoDataGridView.HeaderText.1");
			infoDataGridView.Columns[2].HeaderText = LanguageOper.ReadValue(section, "infoDataGridView.HeaderText.2");
			subToShowLabel.Text = LanguageOper.ReadValue(section, "subToShowLabel.Text");
			rulerDataLabel.Text = LanguageOper.ReadValue(section, "rulerDataLabel.Text");
			subDataLabel.Text = LanguageOper.ReadValue(section, "subDataLabel.Text");
			if (LanguageOper.LocalLanguage != LanguageEnum.EN)
			{
				rulerDataLabel.Location = new Point(176, 319);
				subDataLabel.Location = new Point(579, 319);
			}
			else
			{
				rulerDataLabel.Location = new Point(165, 319);
				subDataLabel.Location = new Point(565, 319);
			}
			checkButton.Text = LanguageOper.ReadValue(section, "checkButton.Text");
			closeButton.Text = LanguageOper.ReadValue(section, "closeButton.Text");
		}

		// 检查输入参数
		private bool checkInputParameter()
		{
			if (specRadioButton.Checked == true)
			{
				int tmpSubIndex = -1;
				bool res = int.TryParse(startSubIndexTextBox.Text.Trim(), out tmpSubIndex);
				if (res == false || tmpSubIndex < 1 || tmpSubIndex > 255)
				{
					string msg = "起始分控序号输入错误：应为 [1,255] 区间的整数";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.0");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return false;
				}
				else
				{
					startSubIndex = tmpSubIndex;
				}

				tmpSubIndex = -1;
				res = int.TryParse(endSubIndexTextBox.Text.Trim(), out tmpSubIndex);
				if (res == false || tmpSubIndex < 1 || tmpSubIndex > 255)
				{
					string msg = "结束分控序号输入错误：应为 [1,255] 区间的整数";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.1");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return false;
				}
				else
				{
					endSubIndex = tmpSubIndex;
				}
			}

			return true;
		}

		// 校验
		private void checkButton_Click(object sender, EventArgs e)
		{
			if (checkInputParameter() == false)
			{
				return;
			}

			allRadioButton.Enabled = false;
			specRadioButton.Enabled = false;
			startSubIndexTextBox.Enabled = false;
			toLabel.Enabled = false;
			endSubIndexTextBox.Enabled = false;
			checkButton.Enabled = false;
			closeButton.Enabled = false;

			Thread t = new Thread(checkSubDataHandle);
			t.IsBackground = true;
			t.Start();
		}

		// 关闭
		private void closeButton_Click(object sender, EventArgs e)
		{
			this.DialogResult = System.Windows.Forms.DialogResult.OK;
		}

		// 切换全部分控、指定分控
		private void specRadioButton_CheckedChanged(object sender, EventArgs e)
		{
			startSubIndexTextBox.Enabled = specRadioButton.Checked;
			endSubIndexTextBox.Enabled = specRadioButton.Checked;
			toLabel.Enabled = specRadioButton.Checked;

			if (specRadioButton.Checked == true)
			{
				checkMode = "spec";
			}
			else
			{
				checkMode = "all";
			}
		}

		// 【主逻辑】分控校验实际过程 - 线程方法
		private void checkSubDataHandle()
		{
			if (checkMode.Equals("all"))
			{
				int subControlNum = baseCoreNet.getSubControlNum();
				if (subControlNum == 0)
				{
					string msg = "当前未检测到分控";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.2");
					}
					
					infoDataGridView.BeginInvoke(showMessageDelegate, msg);
					
					return;
				}
				else
				{
					startSubIndex = 1;
					endSubIndex = subControlNum;
				}
			}
			else
			{
				int subControlNum = baseCoreNet.getSubControlNum();
				if (subControlNum == 0)
				{
					string msg = "当前未检测到分控";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.2");
					}
					
					infoDataGridView.BeginInvoke(showMessageDelegate, msg);

					return;
				}
			}

			isCheckingData = true;

			// 初始化概要信息表格
			infoDataGridView.BeginInvoke(initInfoDataGridDelegate, startSubIndex, endSubIndex);

			// 执行校验过程
			targetSubDataList.Clear();
			int devIndex = baseCoreNet.getActiveDevIndex();
			needReadDataTotalLength = (endSubIndex - startSubIndex + 1) * 9 * 256;
			currentReadedDataLength = 0;
			for (int subIndex = startSubIndex, rowIndex = 0; subIndex <= endSubIndex; subIndex++, rowIndex++)
			{
				string msg = "校验中...";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.3");
				}
				infoDataGridView.BeginInvoke(updateInfoDataGridDelegate, rowIndex, msg);
				string checkResult = checkOneSubControlData(devIndex, subIndex);
				infoDataGridView.BeginInvoke(updateInfoDataGridDelegate, rowIndex, checkResult);
			}
		}

		// 初始化概要信息表格
		private void initInfoDataGrid(int start, int end)
		{
			infoDataGridView.Rows.Clear();
			detailSubIndexComboBox.Items.Clear();
			string subFormatStr = "分控 {0}";
			string unCheckStr = "未校验";
			string detailStr = "详细信息";
			if (LanguageOper.available == true)
			{
				subFormatStr = LanguageOper.ReadValue(section, "msgStr.4");
				unCheckStr = LanguageOper.ReadValue(section, "msgStr.5");
				detailStr = LanguageOper.ReadValue(section, "msgStr.6");
			}
			for (int i = start; i <= end; i++)
			{
				infoDataGridView.Rows.Add(string.Format(subFormatStr, i), unCheckStr, detailStr);
				detailSubIndexComboBox.Items.Add(string.Format(subFormatStr, i));
			}
			detailSubIndexComboBox.SelectedIndex = 0;
		}

		// 更新概要信息表格
		private void updateInfoDataGrid(int rowIndex, string checkResult)
		{
			if (rowIndex < infoDataGridView.Rows.Count)
			{
				infoDataGridView.Rows[rowIndex].Cells[1].Value = checkResult;
			}
		}

		// 更新校验操作进度
		private void updateCheckProgress()
		{
			if (isCheckingData == false)
			{
				return;
			}

			int value = currentReadedDataLength * 100 / needReadDataTotalLength;
			if (value < 0)
			{
				value = 0;
			}
			else if (value > 100)
			{
				value = 100;
			}
			
			checkProgressBar.Value = value;
			progressLabel.Text = value + "%";
			
			if (checkProgressBar.Value == 100)
			{
				string msg = "分控数据校验完成";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.7");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				checkProgressBar.Value = 0;
				progressLabel.Text = "0%";
				detailSubIndexComboBox_SelectedIndexChanged(null, null);
				
				allRadioButton.Enabled = true;
				specRadioButton.Enabled = true;
				startSubIndexTextBox.Enabled = true;
				toLabel.Enabled = true;
				endSubIndexTextBox.Enabled = true;
				checkButton.Enabled = true;
				closeButton.Enabled = true;

				isCheckingData = false;
			}
		}

		// 检查单台分控数据
		private string checkOneSubControlData(int devIndex, int subIndex)
		{
			byte[] replyData = baseCoreNet.readFirmware(devIndex, subIndex, 0x4c0100, 0x4c7200 - 0x4c0100 + 256, false);
			
			byte[] split1 = new byte[256];
			byte[] split2 = new byte[256];
			byte[] split3 = new byte[256];
			byte[] split4 = new byte[256];
			byte[] split5 = new byte[256];
			byte[] split6 = new byte[256];
			byte[] split7 = new byte[256];
			byte[] split8 = new byte[256];
			byte[] split9 = new byte[256];
			Array.Copy(replyData, 0x4c0100 - 0x4c0100, split1, 0, 256);
			Array.Copy(replyData, 0x4c1000 - 0x4c0100, split2, 0, 256);
			Array.Copy(replyData, 0x4c3000 - 0x4c0100, split3, 0, 256);
			Array.Copy(replyData, 0x4c3100 - 0x4c0100, split4, 0, 256);
			Array.Copy(replyData, 0x4c4000 - 0x4c0100, split5, 0, 256);
			Array.Copy(replyData, 0x4c4100 - 0x4c0100, split6, 0, 256);
			Array.Copy(replyData, 0x4c7000 - 0x4c0100, split7, 0, 256);
			Array.Copy(replyData, 0x4c7100 - 0x4c0100, split8, 0, 256);
			Array.Copy(replyData, 0x4c7200 - 0x4c0100, split9, 0, 256);

			byte[] totalSubData = new byte[256 * 9];
			Array.Copy(split1, 0, totalSubData, 256 * 0, 256);
			Array.Copy(split2, 0, totalSubData, 256 * 1, 256);
			Array.Copy(split3, 0, totalSubData, 256 * 2, 256);
			Array.Copy(split4, 0, totalSubData, 256 * 3, 256);
			Array.Copy(split5, 0, totalSubData, 256 * 4, 256);
			Array.Copy(split6, 0, totalSubData, 256 * 5, 256);
			Array.Copy(split7, 0, totalSubData, 256 * 6, 256);
			Array.Copy(split8, 0, totalSubData, 256 * 7, 256);
			Array.Copy(split9, 0, totalSubData, 256 * 8, 256);

			currentReadedDataLength += 256 * 9;
			progressLabel.BeginInvoke(updateCheckProgressDelegate);

			targetSubDataList.Add(totalSubData);

			// 对比分控数据
			bool res = compareSubData(split1, 0x10100, 256) && compareSubData(split2, 0x11000, 256)
				&& compareSubData(split3, 0x13000, 256) && compareSubData(split4, 0x13100, 256)
				&& compareSubData(split5, 0x14000, 256) && compareSubData(split6, 0x14100, 256)
				&& compareSubData(split7, 0x17000, 256) && compareSubData(split8, 0x17100, 256)
				&& compareSubData(split9, 0x17200, 256);

			if (res == true)
			{
				string msg = "校验通过";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.8");
				}
				
				return msg;
			}
			else
			{
				string msg = "校验未通过：sub 数据不一致";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.9");
				}

				return msg;
			}
		}

		// 比较数据
		private bool compareSubData(byte[] splitData, int startAddr, int length)
		{
			try
			{
				for (int i = startAddr; i < startAddr + length; i++)
				{
					if (refSubData[i] != splitData[i - startAddr])
					{
						return false;
					}
				}

				return true;
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
				return false;
			}
		}
		
		// 在 UI 线程显示提示信息
		private void showMessage(string msg)
		{
			MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
		}

		// 要查看的分控发生变化
		private void detailSubIndexComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			int selectIndex = detailSubIndexComboBox.SelectedIndex;
			if (selectIndex < targetSubDataList.Count)
			{
				targetSubDataRichTextBox.Text = Byte2HexString4TargetSub(targetSubDataList[selectIndex]);
			}
			else
			{
				targetSubDataRichTextBox.Text = "";
			}
		}

		// byte[] 转 string
		private string Byte2HexString4TargetSub(byte[] bytes)
		{
			int[] addrArray = new int[] { 0x10100, 0x11000, 0x13000, 0x13100, 0x14000, 0x14100, 0x17000, 0x17100, 0x17200 };
			string splitLine = "---------------------------------------";
			StringBuilder sb = new StringBuilder();
			if (bytes != null && bytes.Length == 9 * 256)
			{
				for (int splitIndex = 0; splitIndex < 9; splitIndex++)
				{
					for (int i = 0; i < 256; i++)
					{
						if (i == 0)
						{
							sb.Append(addrArray[splitIndex].ToString("X8").ToLower().PadLeft(8, '0') + "h: ");
						}
						else if (i > 0 && i % 16 == 0)
						{
							sb.Append("\n" + i.ToString("X8").ToLower().PadLeft(8, '0') + "h: ");
						}
						sb.Append(bytes[i].ToString("X2") + " ");
					}

					if (splitIndex < 8)
					{
						sb.Append(splitLine + "\n");
					}
					else
					{
						sb.Append(splitLine);
					}
				}
			}
			return sb.ToString() + "\n";
		}

		// 窗体关闭前处理
		private void Form_CheckSubData_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (isCheckingData == true)
			{
				string msg = "当前正在执行分控校验操作，请稍后关闭窗口";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.10");
				}

				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				e.Cancel = true;
			}
		}

		// 查看详细信息
		private void infoDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
		{
			if (e.RowIndex >= 0 && e.ColumnIndex == 2)
			{
				if (isCheckingData == true)
				{
					string msg = "尚未完成全部校验，请稍候";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.11");
					}

					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					
					return;
				}
				else
				{
					detailSubIndexComboBox.SelectedIndex = e.RowIndex;
					tabControl1.SelectedIndex = 1;
				}
			}
		}
	}
}
